package com.demo.base.webView.weixin;

import com.demo.base.redis.helper.RedisHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * @author 曳戈泰尔
 * @version 1.0
 * @description 签名类
 * @date 2023/4/4 2:54 PM
 */
@Component
@Slf4j
public class JsSignature {

    /** 注入微信小程序配置 */
    private WeJsConfig weJsConfig;

    @Autowired
    public JsSignature(WeJsConfig weJsConfig) {
        this.weJsConfig = weJsConfig;
    }

    /** 注入Redis */
    private RedisHelper redisHelper;

    @Autowired
    public void setRedisHelper(RedisHelper redisHelper) {
        this.redisHelper = redisHelper;
    }

    /**
     * 获取签名值
     *
     * @param url
     * @return
     */
    public JsApiDto getSignature(String url) {

        String appId = weJsConfig.getAppId();

        // 获取nonceStr
        String nonceStr = UUID.randomUUID().toString();

        // 获取timestamp
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);

        // 获取jspai_ticket
        String jsApiTicket = redisHelper.get("WeXinJsApiTicket");
        if (StringUtils.isBlank(jsApiTicket)) {
            log.error("获取jsapi_ticket失败");

            return null;
        }

        // 4个键值添加到List
        List<String> list =
                Arrays.asList(
                        "jsapi_ticket=" + jsApiTicket,
                        "noncestr=" + nonceStr,
                        "timestamp=" + timestamp,
                        "url=" + url);
        // 数组进行字典排序
        Collections.sort(list);

        // 将四个数据进行组合，传给SHA1进行加密
        StringBuilder waitSignature = new StringBuilder();
        String sep = "";
        for (String s : list) {
            waitSignature.append(sep).append(s);
            sep = "&";
        }

        // sha1加密
        String signature = SHA1(waitSignature.toString());
        if (StringUtils.isBlank(signature)) {
            log.error("签名失败");

            return null;
        }

        return JsApiDto.builder()
                .appId(appId)
                .nonceStr(nonceStr)
                .timestamp(timestamp)
                .signature(signature)
                .url(url)
                .build();
    }

    public String SHA1(String str) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(str.getBytes());
            byte[] messageDigest = digest.digest();

            // Create Hex String
            StringBuilder hexStr = new StringBuilder();

            // 字节数组转换为 十六进制 数
            for (byte b : messageDigest) {
                String shaHex = Integer.toHexString(b & 0xFF);
                if (shaHex.length() < 2) {
                    hexStr.append(0);
                }
                hexStr.append(shaHex);
            }

            return hexStr.toString();

        } catch (NoSuchAlgorithmException e) {
            log.error("签名失败，原因r：{}", e.getMessage());
        }

        return null;
    }
}
